﻿#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "mathlib.h"
#include <cmath>
using namespace std;


complex complex::operator * (const complex& a)
{
    complex c;
    c.real = a.real * this->real - a.imag * this->imag;
    c.imag = a.real * this->imag + a.imag * this->real;
    return c;
}
complex complex::operator * (const float& a)
{
    complex c;
    c.real = a * this->real;
    c.imag = a * this->imag;
    return c;
}

void conjugate_complex(int n, complex *in, complex *out)
{
    int i = 0;
    for (i = 0; i < n; i++) {
        out[i].imag = -in[i].imag;
        out[i].real = in[i].real;
    }
}

void c_abs(complex *f, float *out, int n)
{
    int i = 0;
    float t;
    for (i = 0; i < n; i++) {
        t = f[i].real * f[i].real + f[i].imag * f[i].imag;
        out[i] = sqrt(t);
        out[i] = 20 * (log10(out[i])) - 20 * (log10(1024.0));
    }
}

void c_plus(complex a, complex b, complex *c)
{
    c->real = a.real + b.real;
    c->imag = a.imag + b.imag;
}

void c_sub(complex a, complex b, complex *c)
{
    c->real = a.real - b.real;
    c->imag = a.imag - b.imag;
}

void c_mul(complex a, complex b, complex *c)
{
    c->real = a.real * b.real - a.imag * b.imag;
    c->imag = a.real * b.imag + a.imag * b.real;
}

void c_div(complex a, complex b, complex *c)
{
    c->real = (a.real * b.real + a.imag * b.imag) / (b.real * b.real + b.imag * b.imag);
    c->imag = (a.imag * b.real - a.real * b.imag) / (b.real * b.real + b.imag * b.imag);
}

inline int my_floor(float x)
{
    if (x < 0) {
        return((int)x - 1);
    } else {
        return((int)x);
    }
}

inline int my_ceil(float x)
{
    if (x - (int)x > -0.000001 && x - (int)x < 0.000001) {
        return (int)x;
    } else {
        if (x < 0) {
            return((int)x);
        } else {
            return((int)x + 1);
        }
    }
}

inline int my_round(float x)
{
    //public
    int y;
    if (x < 0) {
        if (x - (int)x >= (-0.5)) {
            y = (int)x;
        } else {
            y = (int)x - 1;
        }
    } else {
        if (x - (int)x >= 0.5) {
            y = (int)x + 1;
        } else {
            y = (int)x;
        }
    }
    return y;
}

void printMatrix(complex **x, int a, int b, char *fileName)
{
    FILE *fp;
    if ((fp = fopen(fileName, "w")) == NULL) {
        cout << "Cannot open pattern file \"" << fileName << "\"." << endl;
        exit(0);
    }
    int i = 0, k = 0;
    for (i = 0; i < a; i++) {
        for (k = 0; k < b; k++) {
            fprintf(fp, "%f\t%f\n", x[i][k].real, x[i][k].imag);
        }
    }
    fclose(fp);
}
void printMatrix(float **x, int a, int b, char *fileName)
{
    FILE *fp;
    if ((fp = fopen(fileName, "w")) == NULL) {
        cout << "Cannot open pattern file \"" << fileName << "\"." << endl;
        exit(0);
    }
    int i = 0, k = 0;
    for (i = 0; i < a; i++) {
        for (k = 0; k < b; k++) {
            fprintf(fp, "%f\n", x[i][k]);
        }
    }
    fclose(fp);
}
void printVector(complex *x, int a, char *fileName)
{
    FILE *fp;
    if ((fp = fopen(fileName, "w")) == NULL) {
        cout << "Cannot open pattern file \"" << fileName << "\"." << endl;
        exit(0);
    }
    int i = 0;
    for (i = 0; i < a; i++) {
        fprintf(fp, "%f %f\n", x[i].real, x[i].imag);
    }
    fclose(fp);
}
void printVector(float *x, int a, char *fileName)
{
    FILE *fp;
    if ((fp = fopen(fileName, "w")) == NULL) {
        cout << "Cannot open pattern file \"" << fileName << "\"." << endl;
        exit(0);
    }
    int i = 0;
    for (i = 0; i < a; i++) {
        fprintf(fp, "%f\n", x[i]);
    }
    fclose(fp);
}

